//
//  AsyncRead.h
//  phosphon.de
//
//  Created by Dirk Lieder on 14.08.09.
//  Copyright 2009 phosphon. All rights reserved.
//


#import "AsyncRead.h"

#define cacheSize 75

@implementation AsyncRead

@synthesize ImageUrl, Image, workInProgress;

static BOOL cacheReady = NO;
static NSMutableDictionary *photoCache;


+(void) initCache{
	
	photoCache = [[NSMutableDictionary alloc] initWithCapacity:cacheSize];
	cacheReady = YES;
}


-(id) initWithUrl:(NSString*)urlToImage
{	
	self = [super init];
	
	if(self)
	{
		if(cacheReady == NO) [AsyncRead initCache];
		
		self.ImageUrl = urlToImage;

	}
	return self;
}


- (void)setDelegate:(id)new_delegate
{
    m_Delegate = new_delegate;
}	

-(void)downloadImage:(id)delegate
{
	m_Delegate = delegate;

	// abort old download
	[self abortDownload];
	
	if([self.ImageUrl length] == 0){ // no image to load
		// set no image image
		self.Image = [UIImage imageNamed:@"Empty.png"];
		if ([m_Delegate respondsToSelector:@selector(internetImageReady:)]) [m_Delegate internetImageReady:self];		

	} else { // to load or from cache
				
		if([photoCache objectForKey:self.ImageUrl]){ // from cache
			
			// aktual date info
			[[photoCache objectForKey:self.ImageUrl] setObject:[NSDate date] forKey:@"date"];
			
			// return cache image
			self.Image = [[photoCache objectForKey:self.ImageUrl] objectForKey:@"image"];
			if ([m_Delegate respondsToSelector:@selector(internetImageReady:)]) [m_Delegate internetImageReady:self];

		} else { // load

			// set loader image
			// self.Image = [UIImage imageNamed:@"Empty.png"];
			if ([m_Delegate respondsToSelector:@selector(internetImageReady:)]) [m_Delegate internetImageReady:self];
		
		
			NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:self.ImageUrl] 
												   cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
			imageConnection = [[NSURLConnection alloc] initWithRequest:imageRequest delegate:self startImmediately:YES];
            
                    
            //NSURLResponse *response;
			//imageConnection = [NSURLConnection sendSynchronousRequest:imageRequest returningResponse:&response error:nil];
            
			if(imageConnection)
			{	//NSLog(@"downloadImage:%@",self.ImageUrl);
				workInProgress = YES;
				m_ImageRequestData = [[NSMutableData data] retain];
			}
		}
	}
}

-(void)abortDownload
{	//NSLog(@"abort");
	if(workInProgress == YES)
	{
		[imageConnection cancel];
		[m_ImageRequestData release];
		workInProgress = NO;
	}
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
	//NSLog(@"didReceiveResponse...");
    // this method is called when the server has determined that it
    // has enough information to create the NSURLResponse
    // it can be called multiple times, for example in the case of a
    // redirect, so each time we reset the data.
    // receivedData is declared as a method instance elsewhere
    [m_ImageRequestData setLength:0];
	
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{	//NSLog(@"append...");
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [m_ImageRequestData appendData:data];	
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    // release the data object
    [m_ImageRequestData release];

    // inform the user
  //  NSLog(@"Connection failed! Error - %@ %@", [error localizedDescription], [[error userInfo] objectForKey:NSErrorFailingURLStringKey]);
	workInProgress = NO;
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
	//NSLog(@"finished...");
	if(workInProgress == YES)
	{
		workInProgress = NO;
		// Create the image with the downloaded data
		UIImage* downloadedImage = [[UIImage alloc] initWithData:m_ImageRequestData];
	
		self.Image = downloadedImage;
	
		// release the data object
		[downloadedImage release];
		[m_ImageRequestData release];
    
		
		// Verify that our delegate responds to the InternetImageReady method
		if ([m_Delegate respondsToSelector:@selector(internetImageReady:)])
		{
			// Call the delegate method and pass ourselves along.
			[m_Delegate internetImageReady:self];
		}
		
		
		// if cache full
		if([photoCache count] > cacheSize){ // clear oldest image
			//NSLog(@"bevoreCache %@",photoCache);
			NSMutableDictionary *cacheDictionary;
			NSMutableDictionary *oldestKey = nil;
			NSDate *oldestDate = [NSDate date];
			
			// get oldest date
			for(cacheDictionary in photoCache){
			
				if([oldestDate compare:[[photoCache objectForKey:cacheDictionary] objectForKey:@"date"]] == NSOrderedDescending){
					oldestDate = [[photoCache objectForKey:cacheDictionary] objectForKey:@"date"];
					oldestKey =cacheDictionary;
				}
			}
	
			// remove oldest image
			[photoCache removeObjectForKey:oldestKey];
			//NSLog(@"afterCache %@",photoCache);
		}
		
		// save into cache if loading OK && not in cache
		if(self.Image && ![photoCache objectForKey:self.ImageUrl]) {
			[photoCache setObject:[[NSMutableDictionary alloc] initWithObjectsAndKeys:self.Image,@"image",[NSDate date],@"date",nil] forKey:self.ImageUrl];
		}
	}	
}


- (void)dealloc 
{	//NSLog(@"dealloc");
    [imageConnection release];
	[ImageUrl release];
	[Image release];
	[super dealloc];
}
@end
